package org.emet.service;

import java.util.Date;
import java.util.List;
import java.util.Map;

import org.emet.dao.FreezerDao;
import org.emet.entity.biz.FreezerRent;
import org.emet.jee.BusinessException;
import org.emet.jee.core.dao.Page;
import org.emet.service.dto.DatePair;
import org.emet.service.dto.FreezerBoxStatus;
import org.emet.service.dto.FreezerCriteria;
import org.hibernate.ObjectNotFoundException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.flex.remoting.RemotingDestination;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@Transactional
@RemotingDestination
public class FreezerRentService {
	@Autowired
	private FreezerDao freezerDao;
	private static Logger logger = LoggerFactory.getLogger(FreezerRentService.class);

	public void save(FreezerRent entity) throws BusinessException {
		if (entity.getStartDate().after(entity.getExpectEndDate()))
			throw new BusinessException("开始时间不能小于结束时间");
		if (!isValidDateRange(entity.getId(), entity.getFreezerId(), entity.getCaseId(), entity.getStartDate(),
				entity.getExpectEndDate()))
			throw new BusinessException("该时间段已经被占用！");
		try {
			freezerDao.save(entity);
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
			throw new BusinessException("发生异常!");
		}
	}

	private boolean isValidDateRange(Long id, Long freezerId, Long caseId, Date startDate, Date endDate) {
		List<DatePair> busyTimeRange = freezerDao.getBusyTimeRange(id, freezerId, caseId);

		for (DatePair dp : busyTimeRange) {
			if (startDate.before(dp.getStartDatetime()) && endDate.after(dp.getStartDatetime()))
				return false;
			else if (startDate.after(dp.getStartDatetime()) && endDate.before(dp.getEndDatetime()))
				return false;
			else if (startDate.before(dp.getEndDatetime()) && endDate.after(dp.getEndDatetime()))
				return false;
			else if (startDate.before(dp.getStartDatetime()) && endDate.after(dp.getEndDatetime()))
				return false;
			else if (startDate.equals(dp.getStartDatetime()) || endDate.equals(dp.getEndDatetime()))
				return false;
		}
		return true;
	}

	@Transactional(readOnly = true)
	public FreezerRent get(Long id) {
		try {
			return freezerDao.get(id);
		} catch (ObjectNotFoundException e) {
			logger.error(e.getMessage(), e);
			throw new BusinessException("发生异常!");
		}
	}

	public void del(Long... ids) {
		for (Long id : ids) {
			if (notExist(id)) {
				continue;
			}
			try {
				freezerDao.delete(id);
			} catch (Exception e) {
				logger.error(e.getMessage(), e);
				throw new BusinessException("发生异常!");
			}
		}
	}

	private boolean notExist(Long id) {
		return get(id) == null;
	}

	@Transactional(readOnly = true)
	public Page<FreezerRent> search(Page<FreezerRent> page, FreezerCriteria criteria) {
		try {
			return freezerDao.search(page, criteria);
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
			throw new BusinessException("发生异常!");
		}
	}

	@Transactional(readOnly = true)
	public List<FreezerBoxStatus> obtainLastestStatus() {
		try {
			return freezerDao.obtainLastestStatus();
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
			throw new BusinessException("发生异常!");
		}
	}

	@Transactional(readOnly = true)
	public List<DatePair> getIdleTimeRange(Long id, Long freezerId, Long caseId) {
		try {
			return freezerDao.getIdleTimeRange(id, freezerId, caseId);
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
			throw new BusinessException("发生异常!");
		}
	}

	//Report
	@Transactional(readOnly = true)
	public List<Map<String, Object>> searchByYear(int startYear, int endYear, boolean groupByName) {
		try {
			return freezerDao.searchByYear(startYear, endYear, groupByName);
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
			throw new BusinessException("发生异常!");
		}
	}

	@Transactional(readOnly = true)
	public List<Map<String, Object>> searchByMon(int startYear, int startMon, int endYear, int endMon,
			boolean groupByName) {
		try {
			return freezerDao.searchByMon(startYear, startMon, endYear, endMon, groupByName);
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
			throw new BusinessException("发生异常!");
		}
	}

	@Transactional(readOnly = true)
	public List<Map<String, Object>> searchByDate(Date startDate, Date endDate, boolean groupByName) {
		try {
			return freezerDao.searchByDate(startDate, endDate, groupByName);
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
			throw new BusinessException("发生异常!");
		}
	}
}
